const dayjs = require('dayjs');
/**
 * 研发项目文档管理模块
 * 负责处理研发项目的文档上传、下载、预览等功能
 */

// 引入基础文件管理模块
const BaseFileManager = require('./base_file_manager');

/**
 * 文档管理器类
 * 用于处理研发项目中的文档管理
 */
class DocManager extends BaseFileManager {
  /**
   * 构造函数
   * @param {Object} page - 页面实例
   * @param {Object} options - 配置选项
   */
  constructor(page, options = {}) {
    super(page, options);
  }

  /**
   * 初始化文档类型
   * @returns {Array} 文档类型列表
   */
  initDocTypes() {
    return [
      { id: 'plan', name: '计划书' },
      { id: 'spec', name: '规格书' },
      { id: 'report', name: '报告' },
      { id: 'test', name: '测试文档' },
      { id: 'guide', name: '指导书' },
      { id: 'other', name: '其他文档' }
    ];
  }

  /**
   * 获取项目文档列表
   * @param {string} projectId - 项目ID
   * @param {boolean} useCache - 是否使用缓存
   * @returns {Promise<Array>} 文档列表
   */
  async getDocuments(projectId, useCache = true) {
    // 检查缓存
    const cacheKey = `documents_${projectId}`;
    const cachedData = useCache ? this.getCache(cacheKey) : null;
    if (cachedData) {
      return cachedData;
    }

    try {
      // 请求服务器数据
      const params = {
        projectId: projectId
      };
      
      const result = await this.callApiWithLoading('research/get_documents', params, '获取文档列表');
      
      // 格式化数据
      if (result && Array.isArray(result)) {
        result.forEach(item => {
          item.DOC_ADD_TIME_DISPLAY = this._formatDateTime(item.DOC_ADD_TIME);
          item.DOC_SIZE_DISPLAY = this.formatFileSize(item.DOC_SIZE || 0);
        });
      }
      
      // 更新缓存
      this.setCache(cacheKey, result || []);
      
      return result || [];
    } catch (error) {
      console.error('获取项目文档列表失败', error);
      throw error;
    }
  }

  /**
   * 获取流程所需文档列表
   * @param {string} projectId - 项目ID
   * @param {string} stateId - 状态ID
   * @returns {Promise<Array>} 所需文档列表
   */
  async getRequiredDocs(projectId, stateId) {
    if (!projectId || !stateId) return [];

    try {
      const params = {
        projectId: projectId,
        stateId: stateId
      };
      
      const result = await this.callApiWithLoading('research/get_required_docs', params, '获取所需文档');
      return result || [];
    } catch (error) {
      console.error('获取流程所需文档列表失败', error);
      throw error;
    }
  }

  /**
   * 上传文档
   * @param {Object} doc - 文档信息
   * @returns {Promise<Object>} 上传结果
   */
  async uploadDoc(doc) {
    if (!doc) return null;
    
    try {
      // 扩展额外的文档信息
      const extraData = {
        flowId: doc.flowId || '',
        eventId: doc.eventId || '',
        desc: doc.desc || ''
      };
      
      // 使用基类的上传文件方法
      return await this.uploadFile(doc, 'document', extraData, 'research/upload_doc');
    } catch (error) {
      console.error('上传文档失败', error);
      throw error;
    }
  }

  /**
   * 预览文档
   * @param {Object} doc - 文档对象
   * @returns {Promise<void>}
   */
  async viewDoc(doc) {
    if (!doc || !doc.DOC_FILE_ID) {
      pageHelper.showError('文档不存在');
      return;
    }

    // 标准化文档对象
    const file = {
      fileId: doc.DOC_FILE_ID,
      name: doc.DOC_NAME
    };

    // 使用基类的预览文件方法
    await this.viewFile(file);
  }

  /**
   * 下载文档
   * @param {Object} doc - 文档对象
   * @returns {Promise<void>}
   */
  async downloadDoc(doc) {
    if (!doc || !doc.DOC_FILE_ID) {
      pageHelper.showError('文档不存在');
      return;
    }

    // 标准化文档对象
    const file = {
      fileId: doc.DOC_FILE_ID,
      name: doc.DOC_NAME
    };

    // 使用基类的下载文件方法
    await this.downloadFile(file);
  }

  /**
   * 批量下载文档
   * @param {Array} docs - 文档列表
   * @returns {Promise<void>}
   */
  async batchDownloadDocs(docs) {
    // 使用基类的批量下载方法
    await this.batchDownloadFiles(docs, 'DOC_FILE_ID', 'DOC_NAME');
  }

  /**
   * 删除文档
   * @param {string} docId - 文档ID
   * @param {string} projectId - 项目ID
   * @returns {Promise<boolean>} 是否删除成功
   */
  async deleteDoc(docId, projectId) {
    const params = { docId };
    
    // 使用基类的删除文件方法
    return await this.deleteFile(docId, projectId, 'research/delete_doc', params);
  }

  /**
   * 检查文档是否已上传
   * @param {string} docName - 文档名称
   * @param {Array} uploadedDocs - 已上传的文档列表
   * @returns {boolean} 是否已上传
   */
  isDocUploaded(docName, uploadedDocs) {
    if (!docName || !uploadedDocs || !Array.isArray(uploadedDocs)) return false;
    
    // 检查是否存在匹配的文档名称
    return uploadedDocs.some(doc => doc.DOC_NAME === docName || doc.docName === docName);
  }

  /**
   * 获取已上传的文档数量
   * @param {Array} uploadedDocs - 已上传的文档列表
   * @param {Array} requiredDocs - 所需的文档列表
   * @returns {Object} 包含已上传数量和总数量的对象
   */
  getUploadedDocCount(uploadedDocs, requiredDocs) {
    if (!uploadedDocs || !Array.isArray(uploadedDocs) || !requiredDocs || !Array.isArray(requiredDocs)) {
      return { uploaded: 0, total: 0 };
    }
    
    // 统计已上传的所需文档数量
    let uploaded = 0;
    for (const requiredDoc of requiredDocs) {
      if (this.isDocUploaded(requiredDoc.name, uploadedDocs)) {
        uploaded++;
      }
    }
    
    return {
      uploaded: uploaded,
      total: requiredDocs.length
    };
  }

  /**
   * 格式化日期时间
   * @private
   * @param {string|Date} datetime - 日期时间
   * @returns {string} 格式化后的日期时间
   */
  _formatDateTime(datetime) {
    if (!datetime) return '';
    
    try {
      // 使用Day.js处理日期
      const date = dayjs(datetime);
      
      // 直接使用Day.js的format方法格式化
      return date.format('YYYY-MM-DD HH:mm:ss');
    } catch (error) {
      console.error('格式化日期时间失败', error);
      return datetime.toString();
    }
  }

  /**
   * 调用API并显示加载中状态
   * @private
   * @param {string} api - API路径
   * @param {Object} params - 请求参数
   * @param {string} loadingText - 加载提示文本
   * @returns {Promise<*>} API响应结果
   */
  async callApiWithLoading(api, params, loadingText) {
    const cloudHelper = require('./helpers/cloud_helper.js');
    const pageHelper = require('./helpers/page_helper.js');
    const timeHelper = require('./helpers/time_helper.js');
    
    try {
      pageHelper.showLoading(loadingText);
      const result = await cloudHelper.callCloudData(api, params);
      pageHelper.hideLoading();
      return result;
    } catch (error) {
      pageHelper.hideLoading();
      throw error;
    }
  }
}

module.exports = DocManager; 